package main

/**
同步锁的方式解决临界资源的安全问题
*/

import (
	"fmt"
	"math/rand"
	"sync"
	"time"
)

// 全局定定义票的数量
var ticket_ = 10

var mutext sync.Mutex // 创建锁

var wg sync.WaitGroup // 同步等待组

func main() {

	/**
	4个子groutine, 模拟4个窗口售票
	*/
	wg.Add(4)
	go saleTicket_("窗口1")
	go saleTicket_("窗口2")
	go saleTicket_("窗口3")
	go saleTicket_("窗口4")

	wg.Wait()
	//time.Sleep(5 * time.Second)
}

/**
窗口买票函数
name 窗口名字
*/
func saleTicket_(name string) {
	// 设置随机睡眠时间
	rand.Seed(time.Now().UnixNano())
	defer wg.Done()
	for {
		// 上锁, 其他子协程不可访问
		mutext.Lock()
		if ticket_ > 0 {
			time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond)
			fmt.Println(name, "当前余票数量: ", ticket_)
			ticket_--
		} else {
			mutext.Unlock()
			fmt.Println(name, "售罄, 没有票了..")
			break
		}
		// 释放锁, 其他的子协程就可以访问了
		mutext.Unlock()
	}

}
